<template>
  <div class="upload-img">
    <!-- 用于浏览 -->
    <div v-if="useScan" class="useScan">
      <el-image 
        v-for="(imgItem, index) in uploadImgs" 
        :key="imgItem.attachmentId" 
        :src="imgItem.fullUrl" 
        :preview-src-list="getImgList(uploadImgs)" 
        :initial-index="index" 
        :style="`width:${width}px;height:${height}px;`"
        preview-teleported>
      </el-image>
    </div>
    <!-- 用于上传 -->
    <div v-else class="useUpload">
      <!-- 多文件上传 -->
      <div v-if="multiple">
        <div 
          class="img-item"
          v-for="(imgItem, index) in uploadImgs" 
          :key="imgItem.attachmentId"
          :style="`width:${width}px;height:${height}px;background-image:url(${imgItem.fullUrl});`"
          @mouseenter="imgItem.show = true"
          @mouseleave="imgItem.show = false" >
          <div v-show="imgItem.show" class="handle-icon">
            <i class="zcytIcon zcyt-delete" @click="doDelete(index)"></i>
          </div>
        </div>
        <el-upload
          v-show="fileList.length < limit"
          v-model:file-list="fileList"
          :show-file-list="false" 
          :multiple="true"
          :limit="limit"
          :before-upload="imgBeforeUpload"
          :on-exceed="doExceed"
          :http-request="doUpload">
          <div class="upload-icon" :class="uploadIcon" :style="`width:${width}px;height:${height}px;font-size:${iconSize}px;`"></div>
        </el-upload>
      </div>
      <!-- 单文件上传 -->
      <el-upload v-else :show-file-list="false" :before-upload="imgBeforeUpload" :http-request="doUpload">
        <el-image v-if="uploadImgs.length === 1" :src="uploadImgs[0].fullUrl" :style="`width:${width}px;height:${height}px;`"></el-image>
        <div v-else class="upload-icon" :class="uploadIcon" :style="`width:${width}px;height:${height}px;font-size:${iconSize}px;`"></div>
      </el-upload>
    </div>
  </div>
</template>

<script setup>
  import { uploadFileApi, getFileUrlApi } from '@/api/api'
  import { imgBeforeUpload } from '@/utils/utils'
  import { ref, getCurrentInstance, watch } from 'vue'

  const currentThis = getCurrentInstance().appContext.config.globalProperties
  defineExpose({init}) // 抛出组件方法供父组件使用

  // 定义父组件传入的值
  const props = defineProps({
    modelValue: String,
    multiple: { // 是否允许上传多个图片
      type: Boolean,
      default: false,
      required: false
    },
    useScan: { // 是否用户浏览
      type: Boolean,
      default: false,
      required: false
    },
    limit: {   // 多文件时候允许上传最大文件数
      type: Number,
      default: 10,
      required: false
    },
    uploadIcon: { // 上传图标
      type: String,
      default: 'zcytIcon zcyt-plus',
      required: false
    },
    iconSize: {  // 上传图标大小
      type: String,
      default: '30',
      required: false
    },
    width: {
      type: String,
      default: '120',
      required: false
    },
    height: {
      type: String,
      default: '120',
      required: false
    },
    iswatch: {
      type: Boolean,
      default: false,
      required: false
    }
  })
  const emits = defineEmits(['update:modelValue'])  // 定义传值给父组件数据方法

  let fileList = ref([])
  let uploadImgs = ref([])

  // 是否需要监听
  if(props.iswatch) {
    watch(() => props.modelValue, (newVal) => {
      init()
    }, {
      immediate: false // 立即监听
    })
  }

  init()
  // 初始化数据
  function init() {
    if(!props.modelValue) {
      uploadImgs.value = []
      return
    }
    getFileUrlApi(props.modelValue).then(res => {
      if(res.code === '200') {
        uploadImgs.value = res.data
        if(props.multiple) {
          res.data.forEach(item => {
            fileList.value.push({name: item.fileName, url: item.fullUrl})
          })
        }
      } else {
        currentThis.$message.error('获取文件地址失败')
      }
    })
  }

  // 上传
  function doUpload(e) {
    let formData = new FormData()
    formData.append('file', e.file)
    uploadFileApi(formData).then(res => {
      if(res.code === '200') {
        if(props.multiple) {
          uploadImgs.value.push({name: e.file.name, ...res.data})
          dataHandle()
        } else {
          uploadImgs.value = [{name: e.file.name, ...res.data}]
          dataHandle()
        }
      } else {
        currentThis.$message.error(res.message)
      }
    })
  }

  // 上传超过允许上传数回调
  function doExceed(e) {
    if((e.length + fileList.value.length) > props.limit) {
      currentThis.$message.error(`最大允许上传${props.limit}张图片`)
    }
  }

  // 删除
  function doDelete(index) {
    let delImgName = uploadImgs.value[index].name
    let delIndex = 0
    for (let i = 0; i < fileList.value.length; i++) {
      if(fileList.value[i].name === delImgName) {
        delIndex = i
        break
      }
    }
    fileList.value.splice(delIndex, 1)
    uploadImgs.value.splice(index, 1)
    dataHandle()
  }

  // 处理数据，并返回数据给父组件
  function dataHandle() {
    let attachmentIds = []
    uploadImgs.value.forEach(item => {
      attachmentIds.push(item.attachmentId)
    })
    emits('update:modelValue', attachmentIds.join(','))
  }

  // 获取图片预览数据
  function getImgList(e) {
    let list = []
    e.forEach(item => {
      list.push(item.fullUrl)
    })
    return list
  }
</script>

<style lang="less" scoped>
.upload-img{
  padding-top: 10px;
  >.useScan{
    display: flex;
    flex-wrap: wrap;
    >.el-image{
      border-radius: 8px;
      margin: 0 10px 10px 0;
    }
  }
  >.useUpload{
    >div{
      display: flex;
      flex-wrap: wrap;
      .img-item{
        position: relative;
        border-radius: 8px;
        background-repeat: no-repeat;
        background-size: 100% 100%;
        margin: 0 10px 10px 0;
        cursor: pointer;
        .handle-icon{
          position: absolute;
          top: 0;
          left: 0;
          z-index: 100;
          width: 100%;
          height: 100%;
          border-radius: 8px;
          display: flex;
          justify-content: center;
          align-items: center;
          background: rgba(0, 0, 0, 0.4);
          >i{
            margin: 0 5px;
            font-size: 25px;
            color: #ffffff;
            &:hover{
              color: #f3550b;
            }
          }
        }
      }
    }
    :deep(.el-upload) {
      .upload-icon{
        border-radius: 8px;
        border: 1px dashed #DCDFE6;
        cursor: pointer;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        color: #DCDFE6;
        &:hover{
          border-color: #409EFF;
        }
        span{
          color: #8a8b8b;
        }
      }
      .el-image{
        border-radius: 8px;
      }
    }
  }
}
</style>